#ifndef VEC4_HPP_
#define VEC4_HPP_

#include "Vec3.hpp"
#include <string>
#include <iostream>
#include <array>

namespace gmath
{
  template <class T> class Vec4
  {
    public:
      Vec4();
      Vec4(T value);
      Vec4(T x, T y, T z, T w);
      Vec4(T* ptr);
      Vec4(Vec3<T>& v, T w);

      const std::array<T, 4>& getData() const;
      void setData(const std::array<T, 4> data);
      void setData(T value);
      void setData(T x, T y, T z, T w);
      void setData(T* ptr);
      void setData(Vec3<T>& v, T w);
      
      T length();
      T dot(Vec4& v2);

      std::string toString();

      Vec4 operator+(Vec4& v2);
      Vec4 operator-(Vec4& v2);
      Vec4 operator*(T a);
      Vec4 operator/(T a);
      Vec4 operator+=(Vec4& v2);
      Vec4 operator-=(Vec4& v2);
      Vec4 operator*=(T a);
      Vec4 operator/=(T a);
      template<typename J> friend std::ostream& 
          operator<<(std::ostream& out, Vec4<J> v);

    private:
      std::array<T, 4> data_;
  };

  typedef Vec4<float> Vec4f;
  typedef Vec4<double> Vec4d;
  typedef Vec4<int> Vec4i;
}

#include "Vec4.inl"

#endif
